package com.qf.bookks.controller;

import com.baomidou.kaptcha.Kaptcha;

import com.qf.bookks.entity.User;
import com.qf.bookks.ex.UserException;
import com.qf.bookks.service.UserService;
import com.qf.bookks.utils.Constants;
import com.qf.bookks.vo.ResultVo;
import com.qf.bookks.vo.TableVo;
import com.qf.bookks.vo.UserRegistVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Autowired
    UserService userService;

    /**
     * 依赖 验证码 核心对象
     */
    @Autowired
    private Kaptcha kaptcha;

    // 处理文件上传路径，使用依赖注入从propeties文件中获取配置
    @Value("${file.upload.path}")
    String fileUploadPath;

    /**
     * 用户登录接口
     * @param username
     * @param password
     * @param captchar
     * @param session
     * @return 通用json数据
     */
    @PostMapping("/login")
    public ResultVo login(String username, String password, String captchar,
                          @RequestParam(value = "switch",required = false) String autologin,
                          HttpServletResponse response,
                          HttpSession session){
        //0. 打印日志，把该web接口收到的参数打印到日志中
        log.debug("接口入参为:username={},password={},captchar={}",username,password,captchar);

        //参数的值是否符合要求

        //1. 校验验证码是否正确
        kaptcha.validate(captchar);

        //2. 查询数据库验证用户名和密码是否匹配
        // 如何设计service层的方法
        // （1） 要把处理业务逻辑所需要的参数都传给该方法
        //  (2) 返回值设计要满足 web接口返回json数据的需求
        User user = userService.login(username,password);

        //3. 根据user是否为null判断登录状态并返回json
        if (user==null){
            // 用户名密码错误导致的登录失败
//            return new ResultVo(-1,"用户名密码错误");
            return ResultVo.error("用户名密码错误");
        }else {
            // 登录成功
            final ResultVo vo = ResultVo.ok();
            vo.put("data",user);

            // 如何保存用户的登录状态
            // 需要在后续的请求到达时，能够判断出发请求的浏览器是否曾经登录过
            session.setAttribute(Constants.USER_LOGIN_SESSION_KEY,user);

            // 添加免登录 cookie生成逻辑
            if (autologin!=null&&autologin.equals("on")){

                final String usertoken = username + "-" + password;

                final Cookie cookie = new Cookie(Constants.AUTOLOGIN_COOKIE_KEY, usertoken);

                // 设置cookie的有效期和cookie的路径
                cookie.setPath("/");  // cookie的路径
                cookie.setMaxAge(60*60*24*14); // 两周的有效期

                response.addCookie(cookie); // 把cookie写回给浏览器

            }


            return vo;
        }

    }

    @RequestMapping("/regist")
    public ResultVo regist(UserRegistVo uv) throws Exception {
        //校验验证码
        final String captchar = uv.getCaptchar();
        kaptcha.validate(captchar);

        userService.regist(uv);
        return ResultVo.ok();
    }
    /**
     * 获取当前登录用户信息
     * @param session
     * @return
     */
    @GetMapping("/currentuser")
    public ResultVo currentUser(HttpSession session){
        // 从session中获取当前登录用户的信息
        final User user = (User) session.getAttribute(Constants.USER_LOGIN_SESSION_KEY);

        final ResultVo vo = ResultVo.ok();
        vo.put("data",user);

        return vo;

    }
    /**
     * 获取当前登录用户头像
     * @param filename
     * @param response
     * @throws IOException
     */
    @GetMapping("/photo")
    public void currentUserPhoto(String filename,HttpServletResponse response) throws IOException {

        final String finalFilePath = fileUploadPath + filename;

        IOUtils.copy(new FileInputStream(finalFilePath),response.getOutputStream());

    }

    @PostMapping("/upload")
    public ResultVo uploadUser(MultipartFile file) throws IOException {

        log.debug("处理批量用户文件上传,file={}",file);

        userService.importUsers(file);

        return ResultVo.ok();

    }

    @GetMapping("/export")
    public ResultVo export(){

        log.debug("全量导出 用户表的数据");

        // 将数据导出逻辑委托给service层处理,返回生成的csv文件的文件名
        String filename = userService.export();

        final ResultVo vo = ResultVo.ok();

        vo.put("data",filename); // 把文件名放入返回的 json的data字段中

        return vo;

    }
    @PostMapping("/update")
    public ResultVo updateUser(User user) throws UserException {
        log.debug("入参为,user={}",user);

        userService.updateUserById(user);

        return ResultVo.ok();

    }
    @PostMapping("/del")
    public ResultVo delUser(String[] ids){

        log.debug("入参为:ids={}",ids);

        userService.delUserByIds(ids);

        return ResultVo.ok();

    }
    @PostMapping("/add")
    public ResultVo addUser(User user) throws UserException {
        log.debug("入参为:user={}",user);

        userService.addUser(user);

        return ResultVo.ok();

    }
    /**
     * 分页查询所有用户数据
     * @param page   当前页号
     * @param limit  页大小
     * @return
     */
    @GetMapping("/getall")
    public TableVo<User> getAll(Integer page,Integer limit){

        log.debug("入参为,page={},limit={}",page,limit);

        TableVo<User> vo = userService.getUserByPage(page,limit);

        return vo;

    }

    @GetMapping("/getallbypagehelper")
    public TableVo<User> getAllByPageHelper(Integer page,Integer limit,
                                            String username,
                                            String sex,
                                            @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){

        log.debug("入参为,page={},limit={},username={},sex={},birthday={}",page,limit,username,sex,birthday);

        TableVo<User> vo = userService.getAllUsersByPageHelper(page,limit,username,sex,birthday);;

        return vo;

    }
    @GetMapping("/get/{id}")
    public User getUser(@PathVariable("id") Integer id){
        return userService.getUser(id);
    }

}
